#include <rtthread.h>

typedef unsigned int u32;
#define r32(addr)           (*(volatile u32 *)(addr))
#define w32(addr, val)      (*(volatile u32 *)(addr) = (val))

#define regRD(offset) r32(0xA0000100 + offset)
#define regWR(offset, val) w32(0xA0000100 + offset, val)
#define RBR 0
#define THR 0
#define DLH 4
#define DLL 0
#define IER 4
#define IIR 8
#define FCR 8
#define LCR 0X0C
#define MCR 0X10
#define LSR 0X14


#define THREAD_STACK_SIZE   256
#define THREAD_PRIORITY     20
#define THREAD_TIMESLICE    10

/* 线程 1 的入口函数 */
static void thread1_entry(void* parameter)
{
    while (1)
    {
        /* 线程 1 采用低优先级运行，一直打印计数值 */
        regWR(THR, 0x11);
        rt_thread_mdelay(1700);
    }
}

/* 线程 2 的入口函数 */
static void thread2_entry(void* parameter)
{
    while (1)
    {
        /* 线程 1 采用低优先级运行，一直打印计数值 */
        regWR(THR, 0x22);
        rt_thread_mdelay(1300);
    }
}

void init(void)
{
    regWR(MCR, 0);
    regWR(LCR, 0x83);
    // 57600 0x01b2
    regWR(DLH, 0x01);
    regWR(DLL, 0xb2);
    // regWR(LCR, 0x03);
    regWR(LCR, 0x2b); // 8-O-1
    // w32(APB_UART1_BASE + 0x04, 0x01); //2
    regWR(IER, 0x01);   // 仅打开接收数据中断
    // regWR(IER, 0x05);   // 打开接收数据中断和链路状态终端 Line Status Interrupt
    // regWR(IER, 0x07);   // 打开接收数据中断和链路状态终端 发送缓冲空中断
    regWR(FCR, 0x07); // no fifo
    // regWR(FCR, 0x47); // 1/4 full fifo
}

int main(void)
{
    rt_thread_t tid = RT_NULL;

    init();



    /* 创建线程 1 */
    tid = rt_thread_create("thread1",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);
    if (tid != RT_NULL)
        rt_thread_startup(tid);


    /* 创建线程 2 */
    tid = rt_thread_create("thread2",
                            thread2_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE-5);
    if (tid != RT_NULL)
        rt_thread_startup(tid);
    
    while (1)
    {
        regWR(THR, 0xaa);
        rt_thread_mdelay(1500);
    }
    
    return 0;
}